package io.renren.modules.workmanagement.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.exception.RRException;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.sys.entity.SysRoleEntity;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.entity.SysUserRoleEntity;
import io.renren.modules.sys.service.SysRoleService;
import io.renren.modules.sys.service.SysUserRoleService;
import io.renren.modules.sys.service.SysUserService;
import io.renren.modules.workmanagement.dao.DepartmentDao;
import io.renren.modules.workmanagement.entity.DepartmentEntity;
import io.renren.modules.workmanagement.enums.RoleEnums;
import io.renren.modules.workmanagement.service.DepartmentService;
import io.renren.modules.workmanagement.to.AssignUser;
import io.renren.modules.workmanagement.utils.PojoUtils;
import io.renren.modules.workmanagement.vo.DepartmentVO;
import io.renren.modules.workmanagement.vo.TeachersAndDepartmentAdminVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


@Service("departmentService")
public class DepartmentServiceImpl extends ServiceImpl<DepartmentDao, DepartmentEntity> implements DepartmentService {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRoleService sysRoleService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String key = (String) params.get("key");
        LambdaQueryWrapper<DepartmentEntity> wrapper = new LambdaQueryWrapper<>();
        List<SysUserEntity> users = sysUserService.likeByName(key);
        if(StringUtils.isNotBlank(key)){
            wrapper.like(DepartmentEntity::getName, "%"+key+"%");
            if(CollectionUtil.isNotEmpty(users)){
                List<Long> userIds = PojoUtils.streamMapList(users, SysUserEntity::getUserId);
                wrapper.or().in(DepartmentEntity::getDepartmentAdminUserId, userIds);
            }
        }
        IPage<DepartmentEntity> page = this.page(
                new Query<DepartmentEntity>().getPage(params),
                wrapper
        );
        List<DepartmentEntity> records = page.getRecords();
        List<DepartmentVO> departmentVOList = records.stream().map(item -> {
            DepartmentVO departmentVO = new DepartmentVO();
            BeanUtils.copyProperties(item, departmentVO);
            SysUserEntity byId = sysUserService.getById(item.getDepartmentAdminUserId());
            departmentVO.setAdminName(byId == null ? null : byId.getName());
            departmentVO.setAdmin(byId == null ? null : byId.getUsername());
            return departmentVO;
        }).collect(Collectors.toList());
        Page<DepartmentVO> departmentVOPage = new Page<>();
        BeanUtils.copyProperties(page, departmentVOPage);
        departmentVOPage.setRecords(departmentVOList);
        return new PageUtils(departmentVOPage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void assignUser(AssignUser assignUser) {
        Long departmentId = assignUser.getId();
        DepartmentEntity departmentEntity = this.lambdaQuery().eq(DepartmentEntity::getId, departmentId).one();
        Long oldDepartmentAdminUserId = departmentEntity.getDepartmentAdminUserId();
        departmentEntity.setDepartmentAdminUserId(assignUser.getAssigneeId());
        this.updateById(departmentEntity);
        SysRoleEntity departmentAdminRole = sysRoleService.getDepartmentAdminRole();

        //给新用户授权
        if (assignUser.getAssigneeId() != null) {
            SysUserEntity sysUserEntity = sysUserService.getById(assignUser.getAssigneeId());
            List<SysUserRoleEntity> sysUserRoleEntityList = sysUserRoleService.getByUserId(sysUserEntity.getUserId());
            List<Long> roleIds = sysUserRoleEntityList.stream().map(SysUserRoleEntity::getRoleId).collect(Collectors.toList());
            if (!roleIds.contains(departmentAdminRole.getRoleId())) {
                roleIds.add(departmentAdminRole.getRoleId());
            }
            sysUserEntity.setRoleIdList(roleIds);
            //保存用户与角色关系
            sysUserRoleService.saveOrUpdate(sysUserEntity.getUserId(), sysUserEntity.getRoleIdList());
        }

        if (oldDepartmentAdminUserId != null && !oldDepartmentAdminUserId.equals(assignUser.getAssigneeId())) {
            //取消旧用户权限
            SysUserEntity oldDepartmentAdminUser = sysUserService.getById(oldDepartmentAdminUserId);
            if (oldDepartmentAdminUser != null) {
                List<SysUserRoleEntity> oldUserRoleEntityList = sysUserRoleService.getByUserId(oldDepartmentAdminUserId);
                List<Long> oldRoleIds = oldUserRoleEntityList.stream().map(SysUserRoleEntity::getRoleId).collect(Collectors.toList());
                DepartmentEntity byAdminId = this.getByAdminId(oldDepartmentAdminUserId);
                oldRoleIds.removeIf(item -> item.equals(departmentAdminRole.getRoleId()) && byAdminId == null);
                oldDepartmentAdminUser.setRoleIdList(oldRoleIds);
                sysUserRoleService.saveOrUpdate(oldDepartmentAdminUser.getUserId(), oldDepartmentAdminUser.getRoleIdList());
            }
        }
    }

    @Override
    public TeachersAndDepartmentAdminVO getTeacherList(Long departmentId) {
        DepartmentEntity departmentEntity = this.lambdaQuery().eq(DepartmentEntity::getId, departmentId).one();
        TeachersAndDepartmentAdminVO departmentSchoolUserVO = new TeachersAndDepartmentAdminVO();
        List<SysRoleEntity> sysRoleList = sysRoleService.getByNotRoleName(RoleEnums.Student.getRoleName());
        List<Long> roleIds = sysRoleList.stream().map(SysRoleEntity::getRoleId).collect(Collectors.toList());
        List<SysUserRoleEntity> userRoleEntityList = sysUserRoleService.getByRoleIds(roleIds);
        Set<Long> userIds = userRoleEntityList.stream().map(SysUserRoleEntity::getUserId).collect(Collectors.toSet());
        if (CollectionUtil.isEmpty(userIds)) {
            return null;
        }
        List<SysUserEntity> userEntities = sysUserService.getByIds(userIds);
        departmentSchoolUserVO.setDepartmentAdminId(departmentEntity.getDepartmentAdminUserId());
        departmentSchoolUserVO.setTeachers(userEntities);
        return departmentSchoolUserVO;
    }

    @Override
    public void saveDepartment(DepartmentEntity department, Long userId) {
        try {
            this.save(department);
        } catch (Exception e) {
            throw new RRException("系部名称重复");
        }
    }

    @Override
    public DepartmentEntity getByAdminId(Long userId) {
        return this.lambdaQuery().eq(DepartmentEntity::getDepartmentAdminUserId, userId).one();
    }

    @Override
    public List<DepartmentEntity> likeByName(String key) {
        return this.lambdaQuery().like(DepartmentEntity::getName, "%" + key + "%").list();
    }
}
